package com.example.designpatterns.interpreter;

import com.example.designpatterns.interpreter.nonterminal.AddExpression;
import com.example.designpatterns.interpreter.nonterminal.ConditionExpression;
import com.example.designpatterns.interpreter.nonterminal.MultiplyExpression;
import com.example.designpatterns.interpreter.nonterminal.SubtractExpression;
import com.example.designpatterns.interpreter.parser.ExpressionParser;
import com.example.designpatterns.interpreter.terminal.NumberExpression;
import com.example.designpatterns.interpreter.terminal.VariableExpression;

import java.util.HashMap;
import java.util.Map;

/**
 * 解释器模式演示
 * 展示如何使用解释器模式解析和计算简单的数学表达式
 */
public class InterpreterPatternDemo {

    public static void main(String[] args) {
        // 创建上下文（变量及其值）
        Map<String, Integer> context = new HashMap<>();
        context.put("x", 10);
        context.put("y", 5);
        
        System.out.println("解释器模式演示：");
        System.out.println("=================");
        
        // 1. 手动构建表达式树示例
        demonstrateManualExpressionBuilding(context);
        
        // 2. 使用解析器构建表达式示例
        demonstrateParserUsage(context);
        
        // 3. 展示复杂表达式：条件表达式
        demonstrateConditionalExpression(context);
    }
    
    private static void demonstrateManualExpressionBuilding(Map<String, Integer> context) {
        System.out.println("\n1. 手动构建表达式树示例：");
        
        // 创建终结符表达式
        Expression x = new VariableExpression("x");
        Expression y = new VariableExpression("y");
        Expression three = new NumberExpression(3);
        
        // 创建表达式: x + (y * 3)
        Expression multiply = new MultiplyExpression(y, three);
        Expression add = new AddExpression(x, multiply);
        
        // 解释并打印结果
        int result = add.interpret(context);
        System.out.println("表达式: " + add);
        System.out.println("计算过程: x + (y * 3) = " + context.get("x") + " + (" + context.get("y") + " * 3)");
        System.out.println("结果: " + result);
    }
    
    private static void demonstrateParserUsage(Map<String, Integer> context) {
        System.out.println("\n2. 使用解析器构建表达式示例：");
        
        // 使用后缀表达式解析器
        ExpressionParser parser = new ExpressionParser();
        
        // 解析后缀表达式: "x y 3 * +" 等价于 x + (y * 3)
        Expression expression = parser.parse("x y 3 * +");
        
        // 解释并打印结果
        int result = expression.interpret(context);
        System.out.println("后缀表达式: x y 3 * +");
        System.out.println("等价中缀表达式: " + expression);
        System.out.println("结果: " + result);
        
        // 解析另一个表达式: "x y -" 等价于 x - y
        Expression subtractExpression = parser.parse("x y -");
        result = subtractExpression.interpret(context);
        System.out.println("\n后缀表达式: x y -");
        System.out.println("等价中缀表达式: " + subtractExpression);
        System.out.println("结果: " + result);
    }
    
    private static void demonstrateConditionalExpression(Map<String, Integer> context) {
        System.out.println("\n3. 条件表达式示例：");
        
        // 创建条件：如果 x > y，则返回 x - y，否则返回 y - x
        Expression x = new VariableExpression("x");
        Expression y = new VariableExpression("y");
        Expression condition = new SubtractExpression(x, y); // x - y > 0 意味着 x > y
        Expression trueCase = new SubtractExpression(x, y);  // x - y
        Expression falseCase = new SubtractExpression(y, x); // y - x
        
        Expression conditionalExp = new ConditionExpression(condition, trueCase, falseCase);
        
        // 解释并打印结果
        int result = conditionalExp.interpret(context);
        System.out.println("条件表达式: " + conditionalExp);
        System.out.println("计算过程: 如果 x > y，则返回 x - y，否则返回 y - x");
        System.out.println("x = " + context.get("x") + ", y = " + context.get("y"));
        System.out.println("结果: " + result);
        
        // 改变上下文，看看结果如何变化
        Map<String, Integer> newContext = new HashMap<>(context);
        newContext.put("x", 3);
        newContext.put("y", 7);
        
        result = conditionalExp.interpret(newContext);
        System.out.println("\n改变变量后:");
        System.out.println("x = " + newContext.get("x") + ", y = " + newContext.get("y"));
        System.out.println("结果: " + result);
    }
} 